package com.biz.primus.ms.oms.service.dispatching;

import com.biz.primus.base.exception.BizSilentException;
import com.biz.primus.model.oms.enums.OrderOperatorSource;
import com.biz.primus.model.oms.enums.OrderState;
import com.biz.primus.model.oms.vo.OrderDispatchingRequest;
import com.biz.primus.model.oms.vo.OrderPostRequest;
import com.biz.primus.ms.oms.dao.po.OmsOrder;
import com.biz.primus.ms.oms.dao.repository.OmsOrderRepository;
import com.biz.primus.model.oms.exception.OmsExceptions;
import com.biz.primus.ms.oms.service.allocation.OrderAllocationService;
import com.biz.primus.ms.oms.service.core.OrderStateService;
import com.biz.primus.ms.oms.service.core.OrderStateService.OrderStateChangeRequest;
import com.biz.primus.ms.oms.service.logs.OrderLogsService;
import com.biz.primus.ms.oms.vo.AllocationRequestVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * @author yanweijin
 * @date 2017/11/8
 */
@Service
@Slf4j
public class OrderDispatchingServiceImpl implements OrderDispatchingService {


	@Autowired
	private OmsOrderRepository omsOrderRepository;

	@Autowired
	private OrderLogsService orderLogsService;

	@Autowired
	private OrderStateService orderStateService;

	@Autowired
	private OrderAllocationService orderAllocationService;

	/**
	 *
	 * 1. 检查门店资格: 订单是否指派给当前门店, 门店是否能够申请改派(有调拨标识的不能申请)
	 * 2. 调取dispatching(req)
	 *
	 * @param req
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void applyDispatching(OrderPostRequest req) {

		OmsOrder omsOrder = omsOrderRepository.findByOrderCode(req.getCode());
		String orderCode = omsOrder.getOrderCode();
		String depotCode = omsOrder.getDepotCode();
		String operator = req.getOperator();
		OrderState state = omsOrder.getState();
		String targetDepotCode = null;

		if(!Objects.equals(depotCode, req.getDepot())){
			orderLogsService.logOrderAllocation(orderCode, depotCode, targetDepotCode,"订单申请改派失败,申请门店与订单门店不匹配!", operator);
			throw new BizSilentException(OmsExceptions.DEPOT_ERROR);
		}
		if(state !=OrderState.allocated && state !=OrderState.printed){
			orderLogsService.logOrderAllocation(orderCode, depotCode, targetDepotCode,"订单申请改派失败,订单状态有误!", operator);
			throw new BizSilentException(OmsExceptions.STATE_ERROR);
		}
		if(omsOrder.isNeedDispatching()){
			orderLogsService.logOrderAllocation(orderCode, depotCode ,targetDepotCode,"订单申请改派失败,订单含调拨标识!", operator);
			throw new BizSilentException(OmsExceptions.DISPATCHING_ORDER);
		}

		OrderDispatchingRequest dispatchingRequest = new OrderDispatchingRequest(req, targetDepotCode, "门店申请改派");

		dispatching(dispatchingRequest);
	}

	/**
	 * 改派
	 *
	 * 2. 检查订单状态: cancel=none, state=allocated,printed
	 * 3. 修改订单状态到 orderBegin, 记录日志
	 * 4. 触发重新分单(事务成功后)
	 * @param req
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dispatching(OrderDispatchingRequest req) {
		OmsOrder omsOrder = omsOrderRepository.findByOrderCode(req.getCode());
		String orderCode = omsOrder.getOrderCode();
		String depotCode = omsOrder.getDepotCode();
		String operator = req.getOperator();
		OrderState state = omsOrder.getState();
		String targetDepotCode = req.getTargetDepotCode();

		if(state !=OrderState.allocated && state !=OrderState.printed){
			orderLogsService.logOrderAllocation(orderCode, depotCode, targetDepotCode,
					"订单申请改派失败,订单状态有误!dispatching log = "+req.getDispatchingLog(), operator);
			throw new BizSilentException(OmsExceptions.STATE_ERROR);
		}
		OrderStateChangeRequest changeReq = OrderStateChangeRequest.builder().order(omsOrder).operator(req.getOperator()).build();
		//修改状态到begin
		orderStateService.backToBegin(changeReq, false);
		orderLogsService.logOrderAllocation(orderCode, depotCode, targetDepotCode,"订单申请改派成功,进入自动分单!dispatching log = "+ req.getDispatchingLog(), operator);

		AllocationRequestVo allocationRequest = AllocationRequestVo.builder().order(omsOrder)
				.targetDepotCode(targetDepotCode).operator(operator)
				.forceAutoAllocation(req.getSource()== OrderOperatorSource.depot).build();

		orderAllocationService.allocateOrder(allocationRequest);
	}




}
